package com.lanhai.system;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lanhai.Main;
import com.lanhai.MainAction;
import com.lanhai.enums.AgvState;
import com.lanhai.enums.TransferType;
import com.lanhai.model.Agv;
import com.lanhai.model.Park;
import com.lanhai.model.Station;
import com.lanhai.utils.CommandUtil;
import com.lanhai.utils.HexUtil;
import com.lanhai.utils.StringUtil;
import com.lanhai.utils.UDPUtil;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;

public class SubmitHandler implements HttpHandler {
	private static final Logger logger = Logger.getLogger(SubmitHandler.class);

	public Main main;

	@Override
	public void handle(HttpExchange httpExchange) {
		try {
			InputStream is = httpExchange.getRequestBody();
			String requestData = is2string(is);
			// System.out.println(httpExchange.getRequestMethod());
			// System.out.println(requestData);
			// String queryParams = httpExchange.getRequestURI().getQuery();
			// System.out.println(queryParams);
			String response = "";
			Map<String, Object> resultMap = new HashMap<String, Object>();
			if (httpExchange.getRequestMethod().equalsIgnoreCase("get")) {
				String queryParams = httpExchange.getRequestURI().getQuery();
				Map<String, String> requestParam = StringUtil.Split(queryParams);
				String requestType = requestParam.get("type");
				if (requestType.equals("ws")) {// websocket相关
					int option = Integer.parseInt(requestParam.get("option"));// 选项
					resultMap.put("success", true);
					switch (option) {
					// 联接
					case 1:
						main.webSocketConn();
						break;
					// 断开
					case 2:
						main.websocketClose();
						break;
					// 发送消息
					case 3:
						String agvNo = requestParam.get("agvNo");
						String msg = requestParam.get("msg");
						main.sendMsgByWs(agvNo, msg);
						break;
					}
					resultMap.put("success", true);
				} else if (requestType.equals("parkAgv")) {
					String sname = requestParam.get("sname");
					Park  p = main.mainAction.getParkByName(sname);
					int agvId = Integer.parseInt(requestParam.get("agvId"));
					p.setAgvId(agvId);
					Map<Integer, Agv> agvMap = main.agvMap;
					for (Map.Entry<Integer, Agv> m : agvMap.entrySet()) {
						if (m.getValue().getLastPoint() == p.getDot() || m.getValue().getGoal() == p.getDot()
								|| m.getValue().getLastPoint() == p.getOutNum()
								|| m.getValue().getGoal() == p.getOutNum() || m.getValue().getParkId() == p.getId()) {
							Agv agv = m.getValue();
							agv.setLastPoint(0);
							agv.setGoal(0);
							agv.setEndPoint(0);
							agv.setParkId(0);
							agvMap.put(agv.getId(), agv);
						}
					}
					main.agvMap = agvMap;
				} else if (requestType.equals("testMp")) {
					int agvId = Integer.parseInt(requestParam.get("agvId"));
					int start = Integer.parseInt(requestParam.get("start"));
					int end = Integer.parseInt(requestParam.get("end"));
					Agv agv = main.agvMap.get(agvId);
					main.mainAction.taskAction.multiPath4z(agv, start, end);
				} else if (requestType.equals("isWait")) {
					String sname = requestParam.get("sname");
					Station station = main.stationMap.get(sname);
					int state = Integer.parseInt(requestParam.get("state"));
					station.setIsWait(state);
					station.setIsWait2(state);
					main.stationMap.put(station.getName(), station);
				} else if (requestType.equals("joinAgv")) {
					String sname = requestParam.get("sname");
					Station station = main.stationMap.get(sname);
					Park p = main.mainAction.getParkByStationName(station.getName());
					Map<Integer, Agv> agvMap = main.agvMap;
					for (Map.Entry<Integer, Agv> m : agvMap.entrySet()) {
						if (m.getValue().getLastPoint() == p.getDot() || m.getValue().getGoal() == p.getDot()
								|| m.getValue().getLastPoint() == p.getOutNum()
								|| m.getValue().getGoal() == p.getOutNum() || m.getValue().getParkId() == p.getId()) {
							Agv agv = m.getValue();
							agv.setLastPoint(0);
							agv.setGoal(0);
							agv.setEndPoint(0);
							agv.setParkId(0);
							agvMap.put(agv.getId(), agv);
						}
					}
					int agvId = Integer.parseInt(requestParam.get("agvId"));
					station.setJoinAgvId(agvId);
					main.agvMap = agvMap;
					main.stationMap.put(station.getName(), station);
				} else if (requestType.equals("ca")) {// 交管相关
					int caId = Integer.parseInt(requestParam.get("caId"));
					main.mainAction.agvAction.releaseControlArea(caId);
					resultMap.put("success", true);
					resultMap.put("msg", "释放交管成功！");
				} else if (requestType.equals("changeLine")) {// 修改AGV的线别
					int agvId = Integer.parseInt(requestParam.get("agvId"));
					int line = Integer.parseInt(requestParam.get("line"));
					Agv agv = main.agvMap.get(agvId);
					agv.setpGroup(line);
					main.agvMap.put(agv.getId(), agv);
					resultMap.put("success", true);
					resultMap.put("msg", "更新线别成功！");
				} else if (requestType.equals("changeStationState")) {// 修改AGV的线别
					String sname = requestParam.get("sname");
					Station station = main.stationMap.get(sname);
					int state = Integer.parseInt(requestParam.get("state"));
					station.setState(state);
					main.stationMap.put(station.getName(), station);
					main.mainAction.updateStation(station.getName());
					resultMap.put("success", true);
					resultMap.put("msg", "启用关闭机台成功！");
				}
				response = JSON.toJSONString(resultMap);
				/*------------------------------GET方法结束-------------------------------*/
			} else {
				JSONObject requestParam = JSONObject.parseObject(new String(requestData));
				String requestType = requestParam.getString("type");
				if (requestType.equals("charger")) {// 测试充电桩
					int cid = requestParam.getInteger("chargerId");
					int action = requestParam.getInteger("action");
					System.out.println("cid:" + cid + ",action:" + action);
					// int channel = 2;
					// byte[] data = CommandUtil.charge(cid, channel, action);
					// String note = "测试充电杆";
					// main.sendData(data, "Charger", cid+"", note, action);
					resultMap.put("success", true);
				} else if (requestType.equals("agv")) {// 测试AGV
					int option = requestParam.getInteger("option");// 选项
					int agvId = requestParam.getInteger("agvId");
					resultMap.put("success", true);
					switch (option) {
					// 向AGV下发重新启动/暂停指令
					case 1:
						int action = requestParam.getInteger("action");// 2:启动,1:停止
						byte[] data = CommandUtil.startOrStop(agvId, action);
						String note = "手动发送AGV启动指令";
						main.sendDataToAgv(data, note, AgvState.XS.getCode());// ctrlState,1、行驶
						resultMap.put("sendData", HexUtil.byte2HexStr(data));
						break;
					// 向AGV下发线路
					case 2:
						int pathId = requestParam.getInteger("pathId");
						data = CommandUtil.pathway(agvId, pathId);
						main.sendDataToAgv(data, "手动让AGV执行" + pathId + "号线路", AgvState.XS.getCode());// ctrlState,1、行驶
						resultMap.put("sendData", HexUtil.byte2HexStr(data));
						break;
					// 向AGV下发传输相关指令
					case 3:
						action = requestParam.getInteger("action");
						data = CommandUtil.transfer(agvId, action);
						String tStr = TransferType.getValueByCode(action);
						int ctrlState = 0;
						if (action == TransferType.SCC.getCode()) {
							ctrlState = AgvState.SCC.getCode();
						} else if (action == TransferType.SCR.getCode()) {
							ctrlState = AgvState.SCR.getCode();
						} else if (action == TransferType.XCC.getCode()) {
							ctrlState = AgvState.XCC.getCode();
						} else if (action == TransferType.XCR.getCode()) {
							ctrlState = AgvState.XCR.getCode();
						} else if (action == TransferType.WC.getCode()) {
							ctrlState = AgvState.ZXWC.getCode();
						}
						main.sendDataToAgv(data, "AGV" + agvId + tStr, ctrlState);
						resultMap.put("sendData", HexUtil.byte2HexStr(data));
						break;
					default:
						resultMap.put("success", false);
						resultMap.put("sendData", "");
						logger.info("没有匹配的操作类型！");
						break;
					}
				} else if (requestType.equals("park")) {// 测试机台
					int parkId = requestParam.getInteger("parkId");
					int action = requestParam.getInteger("action");
					Park park = main.parkMap.get(parkId);
					Station station = main.mainAction.getStationByName(park.getName());
					byte[] data = { HexUtil.hexToByte(park.getName())[0], (byte) action, 0, 0, 0, 0, 0, 0 };
					if (station.getProtocol().equals("udp")) {
						System.out.println(park.getName());
						// data[park.getItem()] = (byte)action;
						UDPUtil.sendData(data, park.getIpAddress(), park.getPort());
					} else {
						String pcIp = main.localIp;
						String plcIp = park.getIpAddress();
						int plcPort = park.getPort();
						int option = 2;// 写入
						int target = station.getWriteTar();
						if (action > 0) {
							byte[] sendByte = CommandUtil.getFinsWriteData(plcIp, plcPort, pcIp, option, target, data);
							byte[] result = UDPUtil.sendData4Fins(sendByte, plcIp, plcPort, option, main.mainAction, 2);
							System.out.println(HexUtil.byte2HexStr(result));
						} else {
							byte[] ndata = { (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
									(byte) 0 };
							byte[] sendByte = CommandUtil.getFinsWriteData(plcIp, plcPort, pcIp, option, target, ndata);
							byte[] result = UDPUtil.sendData4Fins(sendByte, plcIp, plcPort, option, main.mainAction, 2);
							System.out.println(HexUtil.byte2HexStr(result));
						}

					}

					resultMap.put("success", true);
				} else {
					resultMap.put("success", false);
				}
				response = JSON.toJSONString(resultMap);
			}

			// System.out.println("response: " + response);
			is.close();

			Headers responseHeaders = httpExchange.getResponseHeaders();
			responseHeaders.set("Content-Type", "text/json;charset=utf-8");
			responseHeaders.set("Access-Control-Allow-Origin", "*");
			httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.getBytes().length);
			OutputStream os = httpExchange.getResponseBody();
			os.write(response.getBytes());
			os.flush();
			os.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void init(Main main) {
		this.main = main;
	}

	private String is2string(InputStream is) throws IOException {
		final int bufferSize = 1024;
		final char[] buffer = new char[bufferSize];
		final StringBuilder out = new StringBuilder();
		Reader in = new InputStreamReader(is, "UTF-8");

		for (;;) {
			int rsz = in.read(buffer, 0, buffer.length);
			if (rsz < 0)
				break;
			out.append(buffer, 0, rsz);
		}
		return out.toString();
	}

}
